/*
 *  Copright: 2008 Philipp Leitner, Distributed Systems Group,
 *            TU Wien, leitner@infosys.tuwien.ac.at
 *
 *  This file is part of DAIOS.
 *
 *  DAIOS is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation.
 * 
 *  DAIOS is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with DAIOS.  If not, see
 *  <http://www.gnu.org/licenses/>.
 * 
 */

package at.ac.tuwien.infosys.dsg.daiosPlugins.nativeInvoker.converter;

import java.io.InputStream;
import java.util.logging.Logger;

import javax.xml.stream.XMLStreamException;

import org.apache.axiom.om.OMElement;

import at.ac.tuwien.infosys.dsg.daios.exceptions.AmbigiousException;
import at.ac.tuwien.infosys.dsg.daios.framework.interfaces.IConstants;
import at.ac.tuwien.infosys.dsg.daios.framework.structs.DaiosInputMessage;
import at.ac.tuwien.infosys.dsg.daios.framework.structs.DaiosOutputMessage;
import at.ac.tuwien.infosys.dsg.daiosPlugins.axis2.axiom.OMElementRESTConverter;
import at.ac.tuwien.infosys.dsg.daiosPlugins.axis2.axiom.OMUtil;

/**
 * The converter used for converting Daios messages to OM XML models in
 * case of REST invocations through the native backend.
 * 
 * <p>
 * 
 * Internally this converter uses the REST converter from the Axis2 backend
 * to prevent code duplication.
 * 
 * @author philipp
 *
 */
public class RESTConverter {
	
	// the logger
	private Logger log = null;
	// a REST converter from the Axis2 backend 
	private OMElementRESTConverter restConverter = null;
	
	/**
	 * Private constructor. Instances of this converter should
	 * be accessed only via getInstance() .
	 *
	 */
	private RESTConverter() {
		log = Logger.getLogger(IConstants.LOG_NAME);
		restConverter = OMElementRESTConverter.getInstance();
	}
	
	/**
	 * The standard factory method for this converter.
	 * 
	 * @return A new instance of RESTConverter.
	 */
	public static RESTConverter getInstance() {
		return new RESTConverter();
	}
	
	/**
	 * Converts a XML response encoded as java.lang.String
	 * into a DaiosOutputMessage. Since we do not have
	 * any information about the structure of this response
	 * the following mapping rules apply:
	 * 
	 * <pre>
	 *   -- Simple fields are returned as String
	 *   -- Simple array fields are returned as String[]
	 *   -- Complex fields are returned as DaiosMessage
	 *   -- Complex array fields are returned as DaiosMessage[]
	 * </pre>
	 * 
	 * @param string The input document as String
	 * @return The converted DaiosMessage
	 * @throws XMLStreamException
	 */
	public DaiosOutputMessage convert(InputStream is)
		throws XMLStreamException {
		
		return convert(OMUtil.getRootNodeFromIS(is));
		
	}
	
	/**
	 * Converts a DaiosInputMessage to XML. The mapping is controlled
	 * by an 'example' (REST by example).
	 * 
	 * @param message The input message to convert.
	 * @param exampleRoot The example request
	 * @return An XML message as String. The structure of this XML
	 * document is the same as in the given example, but the actual
	 * values are taken from the input message.
	 * @throws AmbigiousException Thrown to indicate that it is not
	 * possible to convert this input message according to the given
	 * example.
	 * @throws XMLStreamException
	 */
	public OMElement convert(DaiosInputMessage message, OMElement exampleRoot)
		throws AmbigiousException, XMLStreamException {
		
		// we re-use the Axis2 Axiom XML model here
		return restConverter.convert(message,
			exampleRoot);
		
	}	
	
	/**
	 * Same as convert(String string), but here the XML document
	 * is already in AXIOM notion.
	 * 
	 * @param node The input document as AXIOM model.
	 * @return The converted DaiosMessage
	 */
	public DaiosOutputMessage convert(OMElement node) {
		
		// we re-use the Axis2 Axiom XML model here
		return restConverter.convert(node);
	
	}
	
}
